{
 "metadata": {
  "signature": "sha256:3c0ef5a3ed5490f677a7f17323826b90f7aa731eabf933f84db51af5b2f58390"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Data acquisition with PyUL\n",
      "======================================================================\n",
      "\n",
      "Introduction\n",
      "------------\n",
      "\n",
      "This pages illustrates the use of the inexpensive (about \\$190) [PMD\n",
      "USB-1208FS](https://www.mccdaq.com/usb-data-acquisition/USB-1208FS.aspx)\n",
      "data acquisition device from [Measurement\n",
      "Computing](http://www.measurementcomputing.com). It makes use of\n",
      "[PyUniversalLibrary](http://www.its.caltech.edu/~astraw/pyul.html), an\n",
      "open-source wrapper of Measurement Computing's [Universal\n",
      "Library](http://www.measurementcomputing.com/cbicatalog/cbiproduct.asp?dept%5Fid=261&pf%5Fid=1084&mscssid=RDNUK9VN7L3L8PL34QF282AX3F987098).\n",
      "\n",
      "See also [Data acquisition with Ni-DAQmx](Data_Acquisition_with_NIDAQmx).\n",
      "\n",
      "The following examples were made with PyUL Release 20050624. The\n",
      "[pre-compiled win32\n",
      "binaries](http://www.its.caltech.edu/~astraw/PyUniversalLibrary/PyUniversalLibrary-20050624.win32-py2.4-num23.7.exe)\n",
      "of this version are compatible with the [Enthought Edition of Python\n",
      "2.4](http://code.enthought.com/enthon/) (Release 1.0.0, 2006-08-02\n",
      "12:20), which is what was used to run these examples.\n",
      "\n",
      "Example 1 - Simple Analog input\n",
      "-------------------------------\n",
      "\n",
      "The first example illustrates the use of the unbuffered analog input:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# example1.py\n",
      "import UniversalLibrary as UL\n",
      "import time\n",
      "\n",
      "BoardNum = 0\n",
      "Gain = UL.BIP5VOLTS\n",
      "Chan = 0\n",
      "\n",
      "tstart = time.time()\n",
      "data = []\n",
      "times = []\n",
      "while 1:\n",
      "    DataValue = UL.cbAIn(BoardNum, Chan, Gain)\n",
      "    data.append( DataValue )\n",
      "    times.append( time.time()-tstart )\n",
      "    if times[-1] > 1.0:\n",
      "        break\n",
      "\n",
      "import pylab\n",
      "pylab.plot(times,data,'o-')\n",
      "pylab.xlabel('time (sec)')\n",
      "pylab.ylabel('ADC units')\n",
      "pylab.show()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "When I ran this, I had a function generator generating a sine wave\n",
      "connected to pins 1 and 2 of my device. This should produce a figure\n",
      "like the following:\n",
      "\n",
      "![](files/attachments/Data_Acquisition_with_PyUL/example1.png)\n",
      "\n",
      "Example 2 - Getting Volts rather than arbitrary units\n",
      "-----------------------------------------------------\n",
      "\n",
      "The values recorded in example 1 are \"ADC units\", the values recorded\n",
      "directly by the Analog-to-Digital hardware. In fact, this device has a\n",
      "12-bit A to D converter, but the values are stored as 16-bit signed\n",
      "integers. To convert these values to Volts, we use Measurement\n",
      "Computing's function. Here we do that for each piece of data and plot\n",
      "the results."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "#example2.py\n",
      "import UniversalLibrary as UL\n",
      "import time\n",
      "\n",
      "BoardNum = 0\n",
      "Gain = UL.BIP5VOLTS\n",
      "Chan = 0\n",
      "\n",
      "tstart = time.time()\n",
      "data = []\n",
      "times = []\n",
      "while 1:\n",
      "    DataValue = UL.cbAIn(BoardNum, Chan, Gain)\n",
      "    EngUnits = UL.cbToEngUnits(BoardNum, Gain, DataValue)\n",
      "    data.append( EngUnits )\n",
      "    times.append( time.time()-tstart )\n",
      "    if times[-1] > 1.0:\n",
      "        break\n",
      "\n",
      "import pylab\n",
      "pylab.plot(times,data,'o-')\n",
      "pylab.xlabel('time (sec)')\n",
      "pylab.ylabel('Volts')\n",
      "#pylab.savefig('example2.png',dpi=72)\n",
      "pylab.show()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Now the output values are in volts:\n",
      "\n",
      "![](files/attachments/Data_Acquisition_with_PyUL/example2.png)\n",
      "\n",
      "Example 3 - Buffered input\n",
      "--------------------------\n",
      "\n",
      "As you have no doubt noticed, the plots above aren't very \"pure\" sine\n",
      "waves. This is undoubtedly due to the way we're sampling the data.\n",
      "Rather than relying on a steady clock to do our acquisition, we're\n",
      "simply polling the device as fast as it (and the operating system) will\n",
      "let us go. There's a better way - we can use the clock on board the\n",
      "Measurement Computing device to acquire a buffer of data at evenly\n",
      "spaced samples."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "#example3.py\n",
      "import UniversalLibrary as UL\n",
      "import Numeric\n",
      "import pylab\n",
      "\n",
      "BoardNum = 0\n",
      "Gain = UL.BIP5VOLTS\n",
      "\n",
      "LowChan = 0\n",
      "HighChan = 0\n",
      "\n",
      "Count = 2000\n",
      "Rate = 3125\n",
      "\n",
      "Options = UL.CONVERTDATA\n",
      "ADData = Numeric.zeros((Count,), Numeric.Int16)\n",
      "\n",
      "ActualRate = UL.cbAInScan(BoardNum, LowChan, HighChan, Count,\n",
      "                   \t Rate, Gain, ADData, Options)\n",
      "\n",
      "# convert to Volts\n",
      "data_in_volts = [ UL.cbToEngUnits(BoardNum, Gain, y) for y in ADData]\n",
      "\n",
      "time = Numeric.arange( ADData.shape[0] )*1.0/ActualRate\n",
      "\n",
      "pylab.plot(time, data_in_volts, 'o-')\n",
      "pylab.xlabel('time (sec)')\n",
      "pylab.ylabel('Volts')\n",
      "pylab.savefig('example3.png',dpi=72)\n",
      "pylab.show()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The output looks much better: ![](files/attachments/Data_Acquisition_with_PyUL/example3.png)\n",
      "\n",
      "Example 4 - computing the power spectrum\n",
      "----------------------------------------\n",
      "\n",
      "Now we can use the function from pylab (part of matplotlib) to compute\n",
      "the power spectral density."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "#example4.py\n",
      "import UniversalLibrary as UL\n",
      "import Numeric\n",
      "import pylab\n",
      "\n",
      "BoardNum = 0\n",
      "Gain = UL.BIP5VOLTS\n",
      "\n",
      "LowChan = 0\n",
      "HighChan = 0\n",
      "\n",
      "Count = 2000\n",
      "Rate = 10000\n",
      "\n",
      "Options = UL.CONVERTDATA\n",
      "ADData = Numeric.zeros((Count,), Numeric.Int16)\n",
      "\n",
      "ActualRate = UL.cbAInScan(BoardNum, LowChan, HighChan, Count,\n",
      "                   \t Rate, Gain, ADData, Options)\n",
      "time = Numeric.arange( ADData.shape[0] )*1.0/ActualRate\n",
      "\n",
      "# convert to Volts\n",
      "data_in_volts = [ UL.cbToEngUnits(BoardNum, Gain, y) for y in ADData]\n",
      "data_in_volts = Numeric.array(data_in_volts) # convert to Numeric array\n",
      "\n",
      "pxx, freqs = pylab.psd( data_in_volts, Fs=ActualRate )\n",
      "decibels = 10*Numeric.log10(pxx)\n",
      "pylab.subplot(2,1,1)\n",
      "pylab.plot(time[100:200],data_in_volts[100:200],'o-') # plot a few samples\n",
      "pylab.xlabel('time (sec)')\n",
      "pylab.ylabel('Volts')\n",
      "pylab.subplot(2,1,2)\n",
      "pylab.plot(freqs, decibels, 'o-')\n",
      "pylab.xlabel('frequency')\n",
      "pylab.ylabel('Power (decibels)')\n",
      "pylab.savefig('example4.png',dpi=72)\n",
      "pylab.show()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "For this example, I've turned up the frequency on the function generator to 480 Hz. You can see, indeed, that's what the `psd()` function tells us:\n",
      "\n",
      "![](files/attachments/Data_Acquisition_with_PyUL/example4.png)\n"
     ]
    }
   ],
   "metadata": {}
  }
 ]
}